package cn.zj.game.config.core;

import cn.zj.game.config.beans.ClassDef;
import cn.zj.game.config.beans.PropDef;
import cn.zj.game.config.type.FieldTypeDefine;
import cn.zj.game.config.utils.ExcelUtil;
import cn.zj.game.config.utils.StringUtil;
import cn.zj.game.config.utils.VmUtil;

import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 通用的数据模型生成
 *
 * @author xi.yang
 * @create 2022-06-22 11:32
 **/
public class GenBean {
    public static void genBeanTsFile() {
        String vmName = "vm/ts/ts.vm";
        Map<String, List<List<String>>> enums = ExcelUtil.getAllExcel2MapList(Paths.get("./beans", "sokoban.xlsx").toString());
        List<ClassDef> classDefs = new ArrayList<>();
        enums.forEach((k, v) -> {
            ClassDef classDef = null;
            String tag = "";
            List<PropDef> propFields = new ArrayList<>();
            for (int i = 1; i < v.size(); i++) {
                List<String> strs = v.get(i);
                String classDoc = strs.get(0);
                String packageName = strs.get(1);
                String className = strs.get(2);
                String fieldName = strs.get(3);
                String fieldType = strs.get(4);
                String fieldDoc = strs.get(5);
                String typeName = "";
                FieldTypeDefine typeDefine = FieldTypeDefine.findByTag(fieldType);
                if (FieldTypeDefine.CLASS.equals(typeDefine) || FieldTypeDefine.ENUM.equals(typeDefine)) {
                    typeName = fieldType.substring(fieldType.indexOf(".") + 1);
                } else {
                    typeName = typeDefine.getTsType();
                }
                boolean array = "1".equals(strs.get(6)) || "1.0".equals(strs.get(6));
                String curTag = StringUtil.isNotBlank(classDoc) ? packageName + className : tag;
                if (!curTag.equals(tag)) {
                    if (classDef != null) {
                        classDef.setPropFields(propFields);
                        classDefs.add(classDef);
                    }
                    tag = curTag;
                    classDef = new ClassDef();
                    propFields = new ArrayList<>();
                }
                if (StringUtil.isNotBlank(classDoc)) {
                    classDef.setJavaDoc(classDoc);
                    classDef.setPackageName(packageName);
                    classDef.setName(className);
                }
                propFields.add(PropDef.builder()
                        .fieldName(fieldName)
                        .fieldType(FieldTypeDefine.findByTag(fieldType))
                        .javaDoc(fieldDoc)
                        .array(array)
                        .typeName(typeName)
                        .build());
            }
            classDef.setPropFields(propFields);
            classDefs.add(classDef);
        });
        for (ClassDef classDef : classDefs) {
            Map<String, Object> map = new HashMap<>();
            map.put("data", classDef);
            String outPath = Paths.get("./demo/" + classDef.getName() + ".ts").toString();
            VmUtil.vmToFile(vmName,map,outPath);
        }
    }
    public static void genBeanJavaFile() {
        String vmName = "vm/java/javaBean.vm";
        Map<String, List<List<String>>> enums = ExcelUtil.getAllExcel2MapList(Paths.get("./", "bean.xlsx").toString());
        List<ClassDef> classDefs = new ArrayList<>();
        enums.forEach((k, v) -> {
            ClassDef classDef = null;
            String tag = "";
            List<PropDef> propFields = new ArrayList<>();
            for (int i = 1; i < v.size(); i++) {
                List<String> strs = v.get(i);
                String classDoc = strs.get(0);
                String packageName = strs.get(1);
                String className = strs.get(2);
                String fieldName = strs.get(3);
                String fieldType = strs.get(4);
                String fieldDoc = strs.get(5);
                String typeName = "";
                FieldTypeDefine typeDefine = FieldTypeDefine.findByTag(fieldType);
                if (FieldTypeDefine.CLASS.equals(typeDefine) || FieldTypeDefine.ENUM.equals(typeDefine)) {
                    typeName = fieldType.substring(fieldType.indexOf(".") + 1);
                } else {
                    typeName = typeDefine.getClazz().getSimpleName();
                }
                boolean array = "1".equals(strs.get(6)) || "1.0".equals(strs.get(6));
                String curTag = StringUtil.isNotBlank(classDoc) ? packageName + className : tag;
                if (!curTag.equals(tag)) {
                    if (classDef != null) {
                        classDef.setPropFields(propFields);
                        classDefs.add(classDef);
                    }
                    tag = curTag;
                    classDef = new ClassDef();
                    propFields = new ArrayList<>();
                }
                if (StringUtil.isNotBlank(classDoc)) {
                    classDef.setJavaDoc(classDoc);
                    classDef.setPackageName(packageName);
                    classDef.setName(className);
                }
                propFields.add(PropDef.builder()
                        .fieldName(fieldName)
                        .fieldType(FieldTypeDefine.findByTag(fieldType))
                        .javaDoc(fieldDoc)
                        .typeName(typeName)
                        .array(array)
                        .build());
            }
            classDef.setPropFields(propFields);
            classDefs.add(classDef);
        });
        for (ClassDef classDef : classDefs) {
            Map<String, Object> map = new HashMap<>();
            map.put("data", classDef);
            String outPath = Paths.get("./demo/" + classDef.getName() + ".java").toString();
            VmUtil.vmToFile(vmName,map,outPath);
        }
    }

    public static void main(String[] args) {
        genBeanJavaFile();
        genBeanTsFile();
    }
}
